﻿
using System;

using SubSonic;

using NUnit.Framework;

namespace TestDB.Data.Test
{
    sealed class TestFaultListDAO
    {
        // ******************************************* //
        #region [ member variables ]

        private static Random m_rand = new Random();
        private static int m_counter = 0;

        #endregion

        // ******************************************* //
        #region [ helper methods ]

        [SetUp]
        public void Setup()
        {
            //SqlQuery deleteItemCmd = DB.Delete().From(FaultItem.Schema).Where(FaultItem.Columns.FaultListId)
            //    .In(new Select(FaultList.Columns.FaultListId).From(FaultList.Schema));
            SqlQuery deleteItemCmd = DB.Delete().From(FaultItem.Schema);
            deleteItemCmd.Execute();

            SqlQuery deleteListCmd = DB.Delete().From(FaultList.Schema);
            deleteListCmd.Execute();
        }

        private static FaultList NewFaultList(int numItems)
        {
            ++m_counter;
            FaultList newList = new FaultList { Name = string.Format("faultlist-{0}", m_counter.ToString()) };

            for (int index = 0; index < numItems; ++index)
            {
                newList.AddFaultItem(TestFaultItemDAO.NewFaultItem());
            }
            return newList;
        }

        #endregion

        // ******************************************* //
        #region [ test ]

        [Test]
        public void TestGenerateId()
        {
            int numItems = 5;

            FaultList newList = NewFaultList(numItems);
            Assert.AreEqual(0, newList.FaultListId);
            Assert.AreEqual(numItems, newList.FaultItemsContained.Count);

            newList.GenerateId();
            Assert.IsTrue(newList.FaultListId > 0);

            foreach (FaultItem item in newList.FaultItemsContained)
            {
                Assert.AreEqual((int)item.FaultListId, newList.FaultListId);
            }
        }

        [Test]
        public void TestInsertSingle()
        {
            int numItems = m_rand.Next(10, 30);

            // -------------------------- insert
            FaultList newList = NewFaultList(numItems);
            Assert.AreEqual(numItems, newList.FaultItemsContained.Count);
            newList.SaveAll();

            // -------------------------- retrieve
            FaultList cpyList = FaultList.FetchByID(newList.FaultListId);
            Assert.AreEqual(numItems, cpyList.FaultItemsContained.Count);
            Assert.AreEqual(newList, cpyList);
        }

        [Test]
        public void TestUpdateSingle()
        {
            int numItems = m_rand.Next(10, 20);

            // -------------------------- insert
            FaultList oriList = NewFaultList(numItems);
            oriList.SaveAll();

            // -------------------------- retrieve
            FaultList cpyList = FaultList.FetchByID(oriList.FaultListId);
            Assert.AreEqual(numItems, cpyList.FaultItemsContained.Count);
            Assert.AreEqual(oriList, cpyList);

            // -------------------------- update and save
            foreach (FaultItem item in oriList.FaultItemsContained)
            {
                // -------------- pre-condition check
                Assert.IsFalse(item.IsNew);
                Assert.IsTrue(item.IsLoaded);

                // -------------- property change
                item.FaultType = 100;
                item.Time = 108;
                item.FaultValue = 800;

                // -------------- post-condition check
                Assert.IsTrue(item.IsDirty);
            }

            int numNewItems = 0;
            for (int index = 0; index < numNewItems; ++index)
            {
                cpyList.AddFaultItem(TestFaultItemDAO.NewFaultItem());
            }
            Assert.AreNotEqual(oriList, cpyList);

            oriList.SaveAll();

            // -------------------------- retrieve again and check
            cpyList = FaultList.FetchByID(oriList.FaultListId);
            Assert.AreEqual(oriList, cpyList);
        }

        [Test]
        public void TestDeleteSingle()
        {
            // --------------------- insert new
            FaultList oriList = NewFaultList(4);
            oriList.SaveAll();

            // --------------------- retrieve to test really inserted in
            FaultList cpyList = FaultList.FetchByID(oriList.FaultListId);
            Assert.AreEqual(oriList, cpyList);

            // --------------------- delete
            oriList.DeleteAll();

            // --------------------- retrieve again to test all are deleted
            FaultList nonExistedList = FaultList.FetchByID(oriList.FaultListId);
            Assert.IsNull(nonExistedList);

            int relatedItemCount = DB.Select()
                .From(FaultItem.Schema)
                .Where(FaultItem.Columns.FaultListId)
                .IsEqualTo(oriList.FaultListId).GetRecordCount();
            Assert.AreEqual(0, relatedItemCount);
        }

        #endregion
    }
}